<template>
    <div class="menu-management">
        <!-- 搜索区域 -->
        <div class="search-area">
            <el-input v-model="searchForm.name" placeholder="请输入菜单名称" style="width: 200px; margin-right: 10px;" />
            <el-input v-model="searchForm.path" placeholder="请输入菜单路径" style="width: 200px; margin-right: 10px;" />
            <el-select v-model="searchForm.type" placeholder="菜单类型" style="width: 150px; margin-right: 10px;" clearable>
                <el-option label="目录" :value="1" />
                <el-option label="菜单" :value="2" />
                <el-option label="按钮" :value="3" />
            </el-select>
            <el-button type="primary" @click="handleSearch" :icon="Search">搜索</el-button>
            <el-button @click="handleReset" :icon="Refresh">重置</el-button>
            <el-button type="success" @click="handleAdd" style="margin-left: 20px;">新增菜单</el-button>
            <el-button type="warning" @click="generateRouteConfig" style="margin-left: 10px;" :icon="Download">生成路由</el-button>
            <el-button type="info" @click="generateVueComponentFile" style="margin-left: 10px;" :icon="Download">生成组件</el-button>
            <el-button type="primary" @click="generateMenuConfigFile" style="margin-left: 10px;" :icon="Download">生成配置</el-button>
        </div>

        <!-- 表格区域 -->
        <el-table :data="tableData" style="width: 100%; margin-top: 20px;" stripe border row-key="id">
            <el-table-column label="序号" width="60" align="center">
                <template #default="scope">
                    {{ (searchForm.pageNum - 1) * searchForm.pageSize + scope.$index + 1 }}
                </template>
            </el-table-column>
            <el-table-column prop="name" label="菜单名称" width="150" align="center" />
            <el-table-column prop="path" label="菜单路径" width="200" align="center" />
            <el-table-column prop="component" label="组件路径" width="200" align="center" />
            <el-table-column prop="icon" label="图标" width="100" align="center">
                <template #default="scope">
                    <el-icon v-if="scope.row.icon">
                        <component :is="scope.row.icon" />
                    </el-icon>
                </template>
            </el-table-column>
            <el-table-column prop="type" label="类型" width="80" align="center">
                <template #default="scope">
                    <el-tag v-if="scope.row.type === 1" type="primary">目录</el-tag>
                    <el-tag v-else-if="scope.row.type === 2" type="success">菜单</el-tag>
                    <el-tag v-else-if="scope.row.type === 3" type="warning">按钮</el-tag>
                </template>
            </el-table-column>
            <el-table-column prop="sort" label="排序" width="80" align="center" />
            <el-table-column prop="status" label="状态" width="80" align="center">
                <template #default="scope">
                    <el-tag v-if="scope.row.status === 1" type="success">启用</el-tag>
                    <el-tag v-else type="danger">禁用</el-tag>
                </template>
            </el-table-column>
            <el-table-column prop="createTime" label="创建时间" width="180" align="center">
                <template #default="scope">
                    {{ formatDate(scope.row.createTime) }}
                </template>
            </el-table-column>
            <el-table-column label="操作" width="200" fixed="right" align="center">
                <template #default="scope">
                    <el-button type="primary" size="small" @click="handleEdit(scope.row)">编辑</el-button>
                    <el-button type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button>
                </template>
            </el-table-column>
        </el-table>

        <!-- 分页 -->
        <div class="pagination-container">
            <el-pagination
                v-model:current-page="searchForm.pageNum"
                v-model:page-size="searchForm.pageSize"
                :page-sizes="[10, 20, 50, 100]"
                layout="total, sizes, prev, pager, next, jumper"
                :total="total"
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
            />
        </div>

        <!-- 菜单表单对话框 -->
        <el-dialog
            v-model="dialogVisible"
            :title="dialogTitle"
            width="600px"
            :before-close="handleDialogClose"
            :close-on-click-modal="false"
        >
            <el-form :model="menuForm" :rules="formRules" ref="menuFormRef" label-width="100px">
                <el-form-item label="上级菜单">
                    <el-tree-select
                        v-model="menuForm.parentId"
                        :data="menuTreeData"
                        :props="treeProps"
                        placeholder="请选择上级菜单"
                        style="width: 100%"
                        clearable
                    />
                </el-form-item>
                <el-form-item label="菜单名称" prop="name">
                    <el-input v-model="menuForm.name" placeholder="请输入菜单名称" />
                </el-form-item>
                <el-form-item label="菜单路径" prop="path">
                    <el-input v-model="menuForm.path" placeholder="请输入菜单路径" />
                </el-form-item>
                <el-form-item label="组件路径" prop="component">
                    <el-input v-model="menuForm.component" placeholder="请输入组件路径" />
                </el-form-item>
                <el-form-item label="菜单图标" prop="icon">
                    <el-input v-model="menuForm.icon" placeholder="请输入图标名称" />
                </el-form-item>
                <el-form-item label="菜单类型" prop="type">
                    <el-radio-group v-model="menuForm.type">
                        <el-radio :label="1">目录</el-radio>
                        <el-radio :label="2">菜单</el-radio>
                        <el-radio :label="3">按钮</el-radio>
                    </el-radio-group>
                </el-form-item>
                <el-form-item label="排序" prop="sort">
                    <el-input-number v-model="menuForm.sort" :min="0" :max="999" />
                </el-form-item>
                <el-form-item label="权限标识" prop="permission">
                    <el-input v-model="menuForm.permission" placeholder="请输入权限标识" />
                </el-form-item>
                <el-form-item label="状态" prop="status">
                    <el-radio-group v-model="menuForm.status">
                        <el-radio :label="1">启用</el-radio>
                        <el-radio :label="0">禁用</el-radio>
                    </el-radio-group>
                </el-form-item>
                <el-form-item label="是否可见" prop="visible">
                    <el-radio-group v-model="menuForm.visible">
                        <el-radio :label="1">显示</el-radio>
                        <el-radio :label="0">隐藏</el-radio>
                    </el-radio-group>
                </el-form-item>
            </el-form>
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="handleDialogClose">取消</el-button>
                    <el-button type="primary" @click="handleSubmit">确定</el-button>
                </span>
            </template>
        </el-dialog>
    </div>
</template>

<script setup>
import { ref, reactive, onMounted, getCurrentInstance, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Search, Refresh, Download } from '@element-plus/icons-vue'
import {
    getMenuList,
    addMenu,
    updateMenu,
    deleteMenu,
    getMenuById,
    getMenuTree,
    getAllMenus
} from '@/api/sys/menu'
import { generateRoutes, generateRouteConfig as generateRouteConfigUtil, generateVueComponent, generateMenuConfig } from '@/utils/routeGenerator'

const { proxy } = getCurrentInstance()

// 搜索表单
const searchForm = reactive({
    pageNum: 1,
    pageSize: 10,
    name: '',
    path: '',
    type: null
})

// 表格数据
const tableData = ref([])
const total = ref(0)

// 对话框控制
const dialogVisible = ref(false)
const dialogTitle = ref('')
const isEdit = ref(false)

// 菜单表单
const menuForm = reactive({
    id: null,
    name: '',
    parentId: 0,
    path: '',
    component: '',
    icon: '',
    sort: 0,
    type: 1,
    permission: '',
    status: 1,
    visible: 1
})

// 菜单树数据
const menuTreeData = ref([])
const treeProps = {
    children: 'children',
    label: 'name',
    value: 'id'
}

// 表单验证规则
const formRules = {
    name: [
        { required: true, message: '请输入菜单名称', trigger: 'blur' },
        { min: 2, max: 20, message: '菜单名称长度在 2 到 20 个字符', trigger: 'blur' }
    ],
    path: [
        { required: true, message: '请输入菜单路径', trigger: 'blur' }
    ],
    type: [
        { required: true, message: '请选择菜单类型', trigger: 'change' }
    ],
    sort: [
        { required: true, message: '请输入排序', trigger: 'blur' }
    ],
    status: [
        { required: true, message: '请选择状态', trigger: 'change' }
    ],
    visible: [
        { required: true, message: '请选择是否可见', trigger: 'change' }
    ]
}

// 初始化
onMounted(() => {
    loadMenuList()
    loadMenuTree()
})

// 监听菜单类型变化，自动生成路径和组件
watch(() => menuForm.type, (newType) => {
    if (newType === 1) {
        // 目录类型，清空组件路径
        menuForm.component = ''
    } else if (newType === 2) {
        // 菜单类型，自动生成组件路径
        if (menuForm.path && !menuForm.component) {
            menuForm.component = menuForm.path.replace(/^\//, '').replace(/\//g, '/')
        }
    } else if (newType === 3) {
        // 按钮类型，清空路径和组件
        menuForm.path = ''
        menuForm.component = ''
    }
})

// 监听菜单名称变化，自动生成权限标识
watch(() => menuForm.name, (newName) => {
    if (newName && !menuForm.permission) {
        // 根据菜单名称自动生成权限标识
        const permission = newName.toLowerCase().replace(/\s+/g, ':')
        menuForm.permission = `${permission}:list`
    }
})

// 监听菜单路径变化，自动生成组件路径
watch(() => menuForm.path, (newPath) => {
    if (newPath && menuForm.type === 2 && !menuForm.component) {
        menuForm.component = newPath.replace(/^\//, '').replace(/\//g, '/')
    }
})

// 加载菜单列表
const loadMenuList = async () => {
    try {
        const res = await getMenuList(searchForm)
        // 添加空值检查和错误处理
        if (res && res.data) {
            tableData.value = res.data.records || []
            total.value = res.data.total || 0
        } else {
            // 如果响应结构不同，尝试直接访问
            tableData.value = res?.records || []
            total.value = res?.total || 0
        }
    } catch (error) {
        console.error('加载菜单列表失败:', error)
        ElMessage.error('加载菜单列表失败')
        tableData.value = []
        total.value = 0
    }
}

// 加载菜单树
const loadMenuTree = async () => {
    try {
        const res = await getMenuTree()
        // 添加空值检查
        const menuData = res?.data || res || []
        // 添加顶级菜单选项
        const treeData = [
            {
                id: 0,
                name: '顶级菜单',
                children: menuData
            }
        ]
        menuTreeData.value = treeData
    } catch (error) {
        console.error('加载菜单树失败:', error)
        ElMessage.error('加载菜单树失败')
        menuTreeData.value = [
            {
                id: 0,
                name: '顶级菜单',
                children: []
            }
        ]
    }
}

// 搜索
const handleSearch = () => {
    searchForm.pageNum = 1
    loadMenuList()
}

// 重置
const handleReset = () => {
    searchForm.name = ''
    searchForm.path = ''
    searchForm.type = null
    searchForm.pageNum = 1
    loadMenuList()
}

// 分页处理
const handleSizeChange = (val) => {
    searchForm.pageSize = val
    loadMenuList()
}

const handleCurrentChange = (val) => {
    searchForm.pageNum = val
    loadMenuList()
}

// 新增菜单
const handleAdd = () => {
    isEdit.value = false
    dialogTitle.value = '新增菜单'
    resetMenuForm()
    dialogVisible.value = true
}

// 编辑菜单
const handleEdit = (row) => {
    isEdit.value = true
    dialogTitle.value = '编辑菜单'
    Object.assign(menuForm, row)
    dialogVisible.value = true
}

// 删除菜单
const handleDelete = (row) => {
    ElMessageBox.confirm(
        `确定要删除菜单"${row.name}"吗？此操作不可撤销。`,
        '删除确认',
        {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
        }
    ).then(async () => {
        try {
            const res = await deleteMenu(row.id)
            const message = res?.data || res || "删除成功"
            ElMessage.success(message)
            loadMenuList()
            loadMenuTree()
        } catch (error) {
            console.error('删除失败:', error)
            ElMessage.error('删除失败')
        }
    }).catch(() => {
        ElMessage.info('已取消删除')
    })
}

// 提交表单
const handleSubmit = () => {
    proxy.$refs.menuFormRef.validate(async (valid) => {
        if (valid) {
            try {
                let res
                if (isEdit.value) {
                    res = await updateMenu(menuForm)
                } else {
                    res = await addMenu(menuForm)
                }
                
                const message = res?.data || res || "操作成功"
                ElMessage.success(message)
                dialogVisible.value = false
                loadMenuList()
                loadMenuTree()
            } catch (error) {
                ElMessage.error('操作失败')
                console.error(error)
            }
        } else {
            ElMessage.warning('请完善表单信息')
        }
    })
}

// 重置菜单表单
const resetMenuForm = () => {
    menuForm.id = null
    menuForm.name = ''
    menuForm.parentId = 0
    menuForm.path = ''
    menuForm.component = ''
    menuForm.icon = ''
    menuForm.sort = 0
    menuForm.type = 1
    menuForm.permission = ''
    menuForm.status = 1
    menuForm.visible = 1
}

// 关闭对话框
const handleDialogClose = () => {
    dialogVisible.value = false
    proxy.$refs.menuFormRef?.resetFields()
}

// 格式化日期
const formatDate = (dateStr) => {
    if (!dateStr) return ''
    const date = new Date(dateStr)
    return date.toLocaleString('zh-CN', {
        year: 'numeric',
        month: '2-digit',
        day: '2-digit',
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit'
    })
}

// 生成路由配置
const generateRouteConfig = async () => {
    try {
        const res = await getMenuTree()
        const menuData = res?.data || res || []
        const routes = generateRoutes(menuData)
        const routeConfig = generateRouteConfigUtil(routes)
        
        // 创建下载链接
        const blob = new Blob([routeConfig], { type: 'text/javascript' })
        const url = URL.createObjectURL(blob)
        const link = document.createElement('a')
        link.href = url
        link.download = 'router.js'
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
        URL.revokeObjectURL(url)
        
        ElMessage.success('路由配置文件已生成并下载')
    } catch (error) {
        ElMessage.error('生成路由配置失败')
        console.error(error)
    }
}

// 生成Vue组件
const generateVueComponentFile = async () => {
    try {
        const res = await getAllMenus()
        const menuData = res?.data || res || []
        const menuMenus = menuData.filter(menu => menu.type === 2 && menu.status === 1)
        
        menuMenus.forEach(menu => {
            if (menu.component) {
                const componentName = menu.component.split('/').pop()
                const componentContent = generateVueComponent(componentName, menu.name)
                
                // 创建下载链接
                const blob = new Blob([componentContent], { type: 'text/vue' })
                const url = URL.createObjectURL(blob)
                const link = document.createElement('a')
                link.href = url
                link.download = `${componentName}.vue`
                document.body.appendChild(link)
                link.click()
                document.body.removeChild(link)
                URL.revokeObjectURL(url)
            }
        })
        
        ElMessage.success(`已生成 ${menuMenus.length} 个Vue组件文件`)
    } catch (error) {
        ElMessage.error('生成Vue组件失败')
        console.error(error)
    }
}

// 生成菜单配置
const generateMenuConfigFile = async () => {
    try {
        const res = await getMenuTree()
        const menuData = res?.data || res || []
        const menuConfig = generateMenuConfig(menuData)
        
        // 创建下载链接
        const blob = new Blob([menuConfig], { type: 'text/javascript' })
        const url = URL.createObjectURL(blob)
        const link = document.createElement('a')
        link.href = url
        link.download = 'menuConfig.js'
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
        URL.revokeObjectURL(url)
        
        ElMessage.success('菜单配置文件已生成并下载')
    } catch (error) {
        ElMessage.error('生成菜单配置失败')
        console.error(error)
    }
}
</script>

<style scoped>
.menu-management {
    padding: 20px;
}

.search-area {
    display: flex;
    align-items: center;
    margin-bottom: 20px;
}

.pagination-container {
    display: flex;
    justify-content: center;
    margin-top: 20px;
}

.dialog-footer {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
}
</style>